#include <gflags/gflags.h>
#include <thread>
#include <butil/logging.h>
#include <brpc/server.h>
#include "spdlogger.hpp"
#include "etcd.hpp"
#include "main.pb.h"

/*
   etcd服务注册与发现 & rpc远程调用联合调试
   1、服务端：定义一个echo服务，服务添加rpc服务器，注册echo服务
   2、客户端：定义一个服务信道管理对象，发现echo服务，rpc调用
*/

DEFINE_bool(mode, false, "日志输出模式，true:发布模式，false:调试模式");
DEFINE_int32(release_level, 0, "发布模式下日志记录等级，此等级以上日志都记录");
DEFINE_string(file, "file.txt", "发布模式下日志输出文件");

DEFINE_string(etcd_url, "http://127.0.0.1:2379", "客户端访问etcd服务的url");
DEFINE_string(server_base_dir, "/services", "服务根目录");
DEFINE_string(echo_server_name, "/echo/instance", "实例名称");
DEFINE_string(echo_server_host, "127.0.0.1:8080", "实例节点的ip&&port");
DEFINE_int32(echo_server_port, 8080, "实例节点的port");


// 继承EchoServer类实现虚方法echo
class EchoServerImpl : public ns_brpc::EchoServer
{
public:
    void echo(google::protobuf::RpcController *controller,
              const ns_brpc::EchoRequest *request,
              ns_brpc::EchoResponse *response,
              google::protobuf::Closure *done)
    {
        // 处理请求
        std::cout << "[MESSAGE]:" << request->message();

        // 定义回显信息，设置响应
        std::string echo_msg = "echo->" + request->message();
        response->set_message(echo_msg);

        // 调用run宣告处理完毕
        // done->Run();
        brpc::ClosureGuard closure_gurad(done); // 智能管理
    }
};

int main(int argc, char *argv[])
{
    // 解析命令行参数
    google::ParseCommandLineFlags(&argc, &argv, true);

    // 初始化日志记录器
    ns_spdlogger::init_logger(FLAGS_mode, FLAGS_release_level, FLAGS_file);

    // 1、创建rpc服务器对象
    brpc::Server server;

    // 2、创建echo服务，将echo服务加入rpc服务器对象
    EchoServerImpl echo_server;
    int ret = server.AddService(&echo_server, brpc::ServiceOwnership::SERVER_DOESNT_OWN_SERVICE); // SERVER_DOESNT_OWN_SERVICE服务添加失败取消服务
    if (ret == -1)
    {
        std::cout << "服务添加失败\n";
        return -1;
    }

    // 3、启动服务器
    brpc::ServerOptions options;   // 定义服务器参数
    options.idle_timeout_sec = -1; // 无数据传输时，指定时间之后关闭连接，-1表示长连接
    options.num_threads = 1;       // io线程数量
    ret = server.Start(FLAGS_echo_server_port, &options);
    if (ret == -1)
    {
        std::cout << "启动服务器失败！\n";
        return -1;
    }

    // 4、服务注册对象
    shared_ptr<ns_etcd::Registry> rgs = make_shared<ns_etcd::Registry>(FLAGS_etcd_url);
    rgs->registry(FLAGS_server_base_dir + FLAGS_echo_server_name, FLAGS_echo_server_host); // 注册echo服务

    // 5、rpc服务器休眠直到 ctrl+c 按下，或者 stop 和 join 服务器
    server.RunUntilAskedToQuit();

    return 0;
}